<?php
// +-------------------------------------------------------------------------------
// | DingZone [ A Rapid Development Framework For Dingtalk ]
// +-------------------------------------------------------------------------------
// | 企业用户 v1.0
// |
// | Copyright (c) 2014-2018 http://www.heimalanshi.com All rights reserved.
// | Author : Jie
// | Date : 2018-08-09
// +-------------------------------------------------------------------------------

namespace app\core\model;

use common\Random;
use common\XXTEAEncryption;
use think\Db;
use think\Model;

class EnterpriseUser extends Model {

    //用户状态
    const STATUS_NORMAL = 1;
    const STATUS_DENY = -1;
    public static $STATUSES = [
        self::STATUS_NORMAL => '正常',
        self::STATUS_DENY => '禁用'
    ];

    //性别
    const SEX_MAN = 1;
    const SEX_WOMAN = 2;
    public static $SEXES = [
        self::SEX_MAN => '男',
        self::SEX_WOMAN => '女'
    ];

    public static function _q($name = false) {
        if (empty($name)) {
            $name = "enterprise_user";
        }
        return Db::name($name);
    }

    /**
     * 解密手机号
     *
     * @param $mobile
     * @return bool|string
     */
    public static function decodeMobile($mobile) {
        if (empty($mobile)) {
            return "";
        }
        return XXTEAEncryption::decrypt($mobile, DEFAULT_DECRYPT_KEY);
    }

    /**
     * 加密手机号
     *
     * @param $mobile
     * @return string
     */
    public static function encodeMobile($mobile) {
        if (empty($mobile)) {
            return "";
        }
        return XXTEAEncryption::encrypt($mobile, DEFAULT_DECRYPT_KEY);
    }

    /**
     * 获取企业的用户总人数
     *
     * @param $eid
     * @return int|string
     */
    public static function getUserCount($eid) {
        return self::_q("enterprise_dept_user")->where([
            'enterprise_id' => $eid,
            'is_deleted' => 0
        ])->count();
    }

    /**
     * 获取用户所在部门id
     *
     * @param $eid
     * @param $userid
     * @return array|false|\PDOStatement|string|\think\Collection
     */
    public static function getUserDeptIds($eid, $userid) {
        return self::_q("enterprise_dept_user")->where([
            'enterprise_id' => $eid,
            'userid' => $userid
        ])->column("deptid");
    }

    /**
     * 获取用户所在的部门信息
     *
     * @param $eid
     * @param $userid
     * @return array|false|\PDOStatement|string|\think\Collection
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function getUserDepts($eid, $userid) {
        $deptUsers = self::_q("enterprise_dept_user")->where([
            'enterprise_id' => $eid,
            'userid' => $userid
        ])->select();
        if (empty($deptUsers)) {
            return [];
        }
        $deptUsers = remap($deptUsers, "deptid");
        $deptids = array_keys($deptUsers);
        $depts = EnterpriseDept::batchGetByIds($eid, $deptids);
        foreach ($depts as &$dept) {
            //在当前部门是否为leader
            $dept['leader'] = fetch(fetch($deptUsers, $dept['id']), "leader", 0);
        }
        return $depts;
    }

    /**
     * 获取用户所在部门名称
     *
     * @param $eid
     * @param $userid
     * @return string
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function getUserDeptTitles($eid, $userid) {
        $depts = self::getUserDepts($eid, $userid);
        $deptTitles = [];
        foreach ($depts as $dept) {
            $deptTitles[] = $dept['title'];
        }
        return join(", ", $deptTitles);
    }


    /**
     * 更新密码
     *
     * @param $eid
     * @param $userid
     * @param $password
     */
    public static function updatePassword($eid, $userid, $password) {
        EnterpriseUser::update([
            'password' => self::generatePassword($password)
        ], [
            'id' => $userid,
            'enterprise_id' => $eid
        ]);
    }

    /**
     * 通过手机号查找用户
     *
     * @param $mobile
     * @param $eid
     * @return array|false|\PDOStatement|string|Model
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function getByMobile($mobile, $eid) {
        $user = self::_q()->where([
            'enterprise_id' => $eid,
            'mobile' => self::encodeMobile($mobile),
            'is_deleted' => 0
        ])->find();

        return $user;
    }

    /**
     * 更新用户信息
     *
     * @param $eid
     * @param $userid
     * @param $data
     * @param $deptids
     * @return bool
     * @throws \think\Exception
     * @throws \think\exception\PDOException
     */
    public static function updateById($eid, $userid, $data, $deptids) {
        if (!empty($data)) {
            if (isset($data['mobile']) && !empty($data['mobile'])) {
                $data['mobile'] = self::encodeMobile($data['mobile']);
            }
            $data['gmt_modified'] = time();
            self::_q()->where([
                'enterprise_id' => $eid,
                'id' => $userid,
                'is_deleted' => 0
            ])->update($data);
        }
        if ($deptids) {
            if (!is_array($deptids)) {
                $deptids = [$deptids];
            }

            //获取现有的用户部门
            $oldDeptIds = self::getUserDeptIds($eid, $userid);

            foreach ($deptids as $deptid) {
                EnterpriseDept::addUserToDept($eid, $userid, $deptid);
            }

            foreach ($oldDeptIds as $oldDeptId) {
                if (!in_array($oldDeptId, $deptids)) {
                    EnterpriseDept::removeUserFromDept($eid, $userid, $oldDeptId);
                }
            }
        }
        return true;
    }

    /**
     * 获取用户信息
     *
     * @param $eid
     * @param $userid
     * @param $decodeMobile
     * @return array|false|\PDOStatement|string|Model
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function getById($eid, $userid, $decodeMobile = false) {
        $user = self::_q()->where([
            'enterprise_id' => $eid,
            'id' => $userid,
            'is_deleted' => 0
        ])->find();
        if (!empty($user) && $decodeMobile) {
            $user['mobile'] = self::decodeMobile($user['mobile']);
        }
        return $user;
    }

    /**
     * 根据用户id批量查询用户信息
     *
     * @param $eid
     * @param $userids
     * @param bool $decodeMobile
     * @return array|false|\PDOStatement|string|\think\Collection
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function batchById($eid, $userids, $decodeMobile = false) {
        if (empty($userids)) {
            return [];
        }
        $users = self::_q()->where([
            'enterprise_id' => $eid,
            'id' => ['in', $userids],
            'is_deleted' => 0
        ])->select();
        if (empty($users)) {
            return [];
        }

        if ($decodeMobile) {
            foreach ($users as &$user) {
                $user['mobile'] = self::decodeMobile($user['mobile']);
            }
        }
        return $users;
    }


    /**
     * 根据用户姓名获取
     *
     * @param $eid
     * @param $showname
     * @param bool $decodeMobile
     * @return array|false|\PDOStatement|string|Model
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function getByShowName($eid, $showname, $decodeMobile = false) {
        $user = self::_q()->where([
            'enterprise_id' => $eid,
            'showname' => $showname,
            'is_deleted' => 0
        ])->find();
        if (!empty($user) && $decodeMobile) {
            $user['mobile'] = self::decodeMobile($user['mobile']);
        }
        return $user;
    }


    /**
     * 添加用户
     *
     * @param $eid
     * @param $user
     * @param null $deptids
     * @return mixed|string
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     */
    public static function add($eid, $user, $deptids = NULL) {
        $existUser = false;
        if (!empty($user['mobile'])) {
            //通过手机号查找
            $existUser = self::getByMobile($user['mobile'], $eid);
            $user['mobile'] = self::encodeMobile($user['mobile']);
        }
        if ($existUser) {
            //存在用户，则更新即可
            $user['id'] = $existUser['id'];
            $user['gmt_modified'] = time();
            self::_q()->where([
                'id' => $existUser['id'],
                'enterprise_id' => $eid
            ])->update($user);
        } else {
            //不存在用户
            if (empty($user['id'])) {
                $user['id'] = 'user_' . Random::get();
            }
            $user['enterprise_id'] = $eid;
            $user['gmt_created'] = time();
            $user['gmt_modified'] = time();
            $user['is_deleted'] = 0;
            self::_q()->insertGetId($user, true);
        }

        if ($deptids) {
            if (!is_array($deptids)) {
                $deptids = [$deptids];
            }
            foreach ($deptids as $deptid) {
                EnterpriseDept::addUserToDept($eid, $user['id'], $deptid);
            }
        }

        return $user['id'];
    }

    /**
     * 获取企业的所有用户
     *
     * @param $eid
     * @return false|\PDOStatement|string|\think\Collection
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function getAll($eid) {
        return self::_q()->where([
            'enterprise_id' => $eid,
            'is_deleted' => 0
        ])->select();
    }

    /**
     * 获取用户id与用户姓名的映射
     *
     * @param $eid
     * @param $limit
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function getUseridShownameMapping($eid, $limit = 0) {
        $rows = self::_q()->where([
            'enterprise_id' => $eid,
            'is_deleted' => 0
        ])->distinct(true)->field("id, showname")->limit($limit)->select();

        $mapping = [];
        foreach ($rows as $row) {
            $mapping[$row['id']] = $row['showname'];
        }
        return $mapping;
    }

    /**
     * 根据用户名密码获取用户
     * @param $username
     * @param $password
     * @param $eid
     * @return bool|mixed
     * @throws \think\exception\DbException
     */
    public static function login($username, $password, $eid) {
        $password = EnterpriseUser::generatePassword($password);
        $ret = EnterpriseUser::get([
            'username' => $username,
            'password' => $password,
            'enterprise_id' => $eid,
            'is_deleted' => 0
        ]);
        if (!$ret) {
            return false;
        }
        $user = $ret->getData();
        self::updateLoginInfo($user['id'], $eid);
        return $user;
    }

    /**
     * 手机号登录
     *
     * @param $mobile
     * @param $password
     * @param $eid
     * @return bool|mixed
     * @throws \think\exception\DbException
     */
    public static function loginByMobile($mobile, $password, $eid) {
        $password = EnterpriseUser::generatePassword($password);
        $ret = EnterpriseUser::get([
            'mobile' => self::encodeMobile($mobile),
            'password' => $password,
            'enterprise_id' => $eid,
            'is_deleted' => 0
        ]);
        if (!$ret) {
            return false;
        }
        $user = $ret->getData();
        self::updateLoginInfo($user['id'], $eid);
        return $user;
    }

    /**
     * 更新登录信息
     *
     * @param $userid
     * @param $eid
     */
    public static function updateLoginInfo($userid, $eid) {
        $user = [];
        $user['gmt_last_login'] = time();
        $user['last_login_ip'] = request()->ip();
        EnterpriseUser::update($user, [
            'id' => $userid,
            'enterprise_id' => $eid
        ]);
    }

    /**
     * 检查用户密码
     *
     * @param $userid
     * @param $password
     * @param $eid
     * @return bool
     * @throws \think\exception\DbException
     */
    public static function checkPassword($userid, $password, $eid) {
        $password = EnterpriseUser::generatePassword($password);
        $ret = EnterpriseUser::get([
            'id' => $userid,
            'enterprise_id' => $eid,
            'password' => $password,
            'is_deleted' => 0
        ]);
        if (!$ret) {
            return false;
        }
        return true;
    }

    /**
     * 生成加密过的密码
     *
     * @param $password
     * @return string
     */
    public static function generatePassword($password) {
        $salt = PASSWORD_SALT;
        return md5(md5($password . $salt) . $salt);
    }

    /**
     * 获取用户名称
     *
     * @param $eid
     * @param $userid
     * @return string
     * @throws \think\exception\DbException
     */
    public static function getShowName($eid, $userid) {
        if ($userid == -1) {
            return "站点管理员";
        }
        $ret = EnterpriseUser::get([
            'id' => $userid,
            'enterprise_id' => $eid,
            'is_deleted' => 0
        ]);
        if (empty($ret)) {
            return "";
        }
        return $ret["showname"];
    }

    /**
     * 分页查询
     *
     * @param $eid
     * @param $departmentId
     * @param $offset
     * @param $size
     * @return array
     * @throws \think\exception\DbException
     */
    public static function selectByDept($eid, $departmentId, $offset, $size) {
        if (empty($departmentId) || $departmentId == EnterpriseDept::ROOT_DEPT_ID) {
            $totalQuery = self::_q()->where("enterprise_id", $eid)->where("is_deleted", 0);
            $query = self::_q()->where("enterprise_id", $eid)->where("is_deleted", 0);
        } else {
            $totalQuery = self::_q("enterprise_dept_user")
                ->where("enterprise_id", $eid)
                ->where("deptid", $departmentId);
            $query = self::_q("enterprise_dept_user `du`")
                ->join(strtoupper("__enterprise_user__ `U`"), "du.userid = U.id and du.enterprise_id = U.enterprise_id")
                ->where("U.is_deleted", 0)
                ->where("du.deptid", $departmentId)
                ->where("du.enterprise_id", $eid)
                ->field("U.*")->limit($offset, $size);
        }

        $total = $totalQuery->count();
        $userlist = $query->select();

        return [
            'total' => $total,
            'hasMore' => $total > count($userlist),
            'userlist' => $userlist
        ];
    }

    /**
     * 将钉钉用户信息缓存到本地
     *
     * @param $dingUser
     * @param $eid
     * @return array|bool
     * @throws \think\exception\DbException
     */
    public static function syncDing($dingUser, $eid) {
        if (empty($dingUser)) {
            return false;
        }

        $user = [
            'id' => $dingUser['userid'],
            'username' => fetch($dingUser, 'jobnumber', ""),
            'enterprise_id' => $eid,
            'avatar' => fetch($dingUser, 'avatar'),
            'is_admin' => fetch($dingUser, 'isAdmin', false),
            'showname' => fetch($dingUser, 'name', ""),
            'is_senior' => fetch($dingUser, 'isSenior', false),
            'openid' => fetch($dingUser, 'openId', ""),
            'dingid' => fetch($dingUser, 'dingId', ""),
            'unionid' => fetch($dingUser, 'unionid', ""),
            'jobnumber' => fetch($dingUser, 'jobnumber', ""),
            'position' => fetch($dingUser, 'position', ""),
            'mobile' => self::encodeMobile(fetch($dingUser, 'mobile', ''), DEFAULT_DECRYPT_KEY)
        ];

        $ret = EnterpriseUser::get([
            'id' => $dingUser['userid'],
            'enterprise_id' => $eid
        ]);

        if ($ret && $ret->getData()) {
            // 已经存在，则进行更新
            EnterpriseUser::update($user, [
                'id' => $dingUser['userid'],
                'enterprise_id' => $eid
            ]);
        } else {
            $user['gmt_created'] = time();
            EnterpriseUser::create($user);
        }

        return $user;
    }
}